// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.iso;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.HashMap;
import zombie.Lua.LuaEventManager;
import zombie.core.Core;
import zombie.core.Rand;
import zombie.core.znet.SteamUtils;
import zombie.debug.DebugLog;
import zombie.erosion.ErosionRegions;
import zombie.erosion.season.ErosionIceQueen;
import zombie.gameStates.GameLoadingState;
import zombie.gameStates.IngameState;
import zombie.globalObjects.GlobalObjectLookup;
import zombie.iso.sprite.IsoSprite;
import zombie.iso.sprite.IsoSpriteManager;
import zombie.network.CoopSlave;
import zombie.network.GameClient;
import zombie.network.GameServer;
import zombie.network.ServerMap;
import zombie.network.ServerOptions;
import zombie.vehicles.VehicleManager;
import zombie.world.WorldDictionary;
import zombie.world.WorldDictionaryException;

public final class WorldConverter {
    public static final WorldConverter instance = new WorldConverter();
    public static boolean converting;
    public HashMap<Integer, Integer> TilesetConversions = null;
    int oldID = 0;

    public void convert(String worldName, IsoSpriteManager manager) throws IOException {
        File file = new File(zombie.ZomboidFileSystem.instance.getGameModeCacheDir() + File.separator + worldName + File.separator + "map_ver.bin");
        if (file.exists()) {
            converting = true;
            FileInputStream fileInputStream = new FileInputStream(file);
            DataInputStream dataInputStream = new DataInputStream(fileInputStream);
            int _int = dataInputStream.readInt();
            dataInputStream.close();
            if (_int < 195) {
                if (_int < 24) {
                    GameLoadingState.build23Stop = true;
                    return;
                }

                try {
                    this.convert(worldName, _int, 195);
                } catch (Exception exception) {
                    IngameState.createWorld(worldName);
                    IngameState.copyWorld(worldName + "_backup", worldName);
                    exception.printStackTrace();
                }
            }

            converting = false;
        }
    }

    private void convert(String string1, int int0, int int1) {
        if (!GameClient.bClient) {
            GameLoadingState.convertingWorld = true;
            String string0 = Core.GameSaveWorld;
            IngameState.createWorld(string1 + "_backup");
            IngameState.copyWorld(string1, Core.GameSaveWorld);
            Core.GameSaveWorld = string0;
            if (int1 >= 14 && int0 < 14) {
                try {
                    this.convertchunks(string1, 25, 25);
                } catch (IOException iOException0) {
                    iOException0.printStackTrace();
                }
            } else if (int0 == 7) {
                try {
                    this.convertchunks(string1);
                } catch (IOException iOException1) {
                    iOException1.printStackTrace();
                }
            }

            if (int0 <= 4) {
                this.loadconversionmap(int0, "tiledefinitions");
                this.loadconversionmap(int0, "newtiledefinitions");

                try {
                    this.convertchunks(string1);
                } catch (IOException iOException2) {
                    iOException2.printStackTrace();
                }
            }

            GameLoadingState.convertingWorld = false;
        }
    }

    private void convertchunks(String string0) throws IOException {
        IsoCell isoCell = new IsoCell(300, 300);
        IsoChunkMap isoChunkMap = new IsoChunkMap(isoCell);
        File file = new File(zombie.ZomboidFileSystem.instance.getGameModeCacheDir() + File.separator + string0 + File.separator);
        if (!file.exists()) {
            file.mkdir();
        }

        String[] string1 = file.list();

        for (String string2 : string1) {
            if (string2.contains(".bin")
                && !string2.equals("map.bin")
                && !string2.equals("map_p.bin")
                && !string2.matches("map_p[0-9]+\\.bin")
                && !string2.equals("map_t.bin")
                && !string2.equals("map_c.bin")
                && !string2.equals("map_ver.bin")
                && !string2.equals("map_sand.bin")
                && !string2.equals("map_mov.bin")
                && !string2.equals("map_meta.bin")
                && !string2.equals("map_cm.bin")
                && !string2.equals("pc.bin")
                && !string2.startsWith("zpop_")
                && !string2.startsWith("chunkdata_")) {
                String[] string3 = string2.replace(".bin", "").replace("map_", "").split("_");
                int int0 = Integer.parseInt(string3[0]);
                int int1 = Integer.parseInt(string3[1]);
                isoChunkMap.LoadChunkForLater(int0, int1, 0, 0);
                isoChunkMap.SwapChunkBuffers();
                isoChunkMap.getChunk(0, 0).Save(true);
            }
        }
    }

    private void convertchunks(String string0, int int0, int int1) throws IOException {
        IsoCell isoCell = new IsoCell(300, 300);
        new IsoChunkMap(isoCell);
        File file0 = new File(zombie.ZomboidFileSystem.instance.getGameModeCacheDir() + File.separator + string0 + File.separator);
        if (!file0.exists()) {
            file0.mkdir();
        }

        String[] string1 = file0.list();
        IsoWorld.saveoffsetx = int0;
        IsoWorld.saveoffsety = int1;
        IsoWorld.instance.MetaGrid.Create();
        WorldStreamer.instance.create();

        for (String string2 : string1) {
            if (string2.contains(".bin")
                && !string2.equals("map.bin")
                && !string2.equals("map_p.bin")
                && !string2.matches("map_p[0-9]+\\.bin")
                && !string2.equals("map_t.bin")
                && !string2.equals("map_c.bin")
                && !string2.equals("map_ver.bin")
                && !string2.equals("map_sand.bin")
                && !string2.equals("map_mov.bin")
                && !string2.equals("map_meta.bin")
                && !string2.equals("map_cm.bin")
                && !string2.equals("pc.bin")
                && !string2.startsWith("zpop_")
                && !string2.startsWith("chunkdata_")) {
                String[] string3 = string2.replace(".bin", "").replace("map_", "").split("_");
                int int2 = Integer.parseInt(string3[0]);
                int int3 = Integer.parseInt(string3[1]);
                IsoChunk isoChunk = new IsoChunk(isoCell);
                isoChunk.refs.add(isoCell.ChunkMap[0]);
                WorldStreamer.instance.addJobConvert(isoChunk, 0, 0, int2, int3);

                while (!isoChunk.bLoaded) {
                    try {
                        Thread.sleep(20L);
                    } catch (InterruptedException interruptedException0) {
                        interruptedException0.printStackTrace();
                    }
                }

                isoChunk.wx += int0 * 30;
                isoChunk.wy += int1 * 30;
                isoChunk.jobType = IsoChunk.JobType.Convert;
                isoChunk.Save(true);
                File file1 = new File(zombie.ZomboidFileSystem.instance.getGameModeCacheDir() + File.separator + string0 + File.separator + string2);

                while (!ChunkSaveWorker.instance.toSaveQueue.isEmpty()) {
                    try {
                        Thread.sleep(13L);
                    } catch (InterruptedException interruptedException1) {
                        interruptedException1.printStackTrace();
                    }
                }

                file1.delete();
            }
        }
    }

    private void loadconversionmap(int int0, String string1) {
        String string0 = "media/" + string1 + "_" + int0 + ".tiles";
        File file = new File(string0);
        if (file.exists()) {
            try {
                RandomAccessFile randomAccessFile = new RandomAccessFile(file.getAbsolutePath(), "r");
                int int1 = IsoWorld.readInt(randomAccessFile);

                for (int int2 = 0; int2 < int1; int2++) {
                    Thread.sleep(4L);
                    String string2 = IsoWorld.readString(randomAccessFile);
                    String string3 = string2.trim();
                    IsoWorld.readString(randomAccessFile);
                    int int3 = IsoWorld.readInt(randomAccessFile);
                    int int4 = IsoWorld.readInt(randomAccessFile);
                    int int5 = IsoWorld.readInt(randomAccessFile);

                    for (int int6 = 0; int6 < int5; int6++) {
                        IsoSprite isoSprite = (IsoSprite)IsoSpriteManager.instance.NamedMap.get(string3 + "_" + int6);
                        if (this.TilesetConversions == null) {
                            this.TilesetConversions = new HashMap();
                        }

                        this.TilesetConversions.put(this.oldID, isoSprite.ID);
                        this.oldID++;
                        int int7 = IsoWorld.readInt(randomAccessFile);

                        for (int int8 = 0; int8 < int7; int8++) {
                            string2 = IsoWorld.readString(randomAccessFile);
                            String string4 = string2.trim();
                            string2 = IsoWorld.readString(randomAccessFile);
                            String string5 = string2.trim();
                        }
                    }
                }
            } catch (Exception exception) {
            }
        }
    }

    public void softreset() throws WorldDictionaryException {
        String string0 = GameServer.ServerName;
        Core.GameSaveWorld = string0;
        IsoCell isoCell = new IsoCell(300, 300);
        IsoChunk isoChunk = new IsoChunk(isoCell);
        File file = new File(zombie.ZomboidFileSystem.instance.getGameModeCacheDir() + File.separator + string0 + File.separator);
        if (!file.exists()) {
            file.mkdir();
        }

        String[] string1 = file.list();
        if (CoopSlave.instance != null) {
            CoopSlave.instance.sendMessage("softreset-count", null, Integer.toString(string1.length));
        }

        IsoWorld.instance.MetaGrid.Create();
        ServerMap.instance.init(IsoWorld.instance.MetaGrid);
        new ErosionIceQueen(IsoSpriteManager.instance);
        ErosionRegions.init();
        WorldStreamer.instance.create();
        VehicleManager.instance = new VehicleManager();
        WorldDictionary.init();
        GlobalObjectLookup.init(IsoWorld.instance.getMetaGrid());
        LuaEventManager.triggerEvent("OnSGlobalObjectSystemInit");
        int int0 = string1.length;
        DebugLog.log("processing " + int0 + " files");

        for (String string2 : string1) {
            int0--;
            if (string2.startsWith("zpop_")) {
                deleteFile(string2);
            } else if (string2.equals("map_t.bin")) {
                deleteFile(string2);
            } else if (string2.equals("map_meta.bin") || string2.equals("map_zone.bin")) {
                deleteFile(string2);
            } else if (string2.equals("reanimated.bin")) {
                deleteFile(string2);
            } else if (string2.matches("map_[0-9]+_[0-9]+\\.bin")) {
                System.out.println("Soft clearing chunk: " + string2);
                String[] string3 = string2.replace(".bin", "").replace("map_", "").split("_");
                int int1 = Integer.parseInt(string3[0]);
                int int2 = Integer.parseInt(string3[1]);
                isoChunk.refs.add(isoCell.ChunkMap[0]);
                isoChunk.wx = int1;
                isoChunk.wy = int2;
                ServerMap.instance.setSoftResetChunk(isoChunk);
                WorldStreamer.instance.addJobWipe(isoChunk, 0, 0, int1, int2);

                while (!isoChunk.bLoaded) {
                    try {
                        Thread.sleep(20L);
                    } catch (InterruptedException interruptedException) {
                        interruptedException.printStackTrace();
                    }
                }

                isoChunk.jobType = IsoChunk.JobType.Convert;
                isoChunk.FloorBloodSplats.clear();

                try {
                    isoChunk.Save(true);
                } catch (Exception exception) {
                    exception.printStackTrace();
                }

                ServerMap.instance.clearSoftResetChunk(isoChunk);
                isoChunk.doReuseGridsquares();
                IsoChunkMap.chunkStore.remove(isoChunk);
                if (int0 % 100 == 0) {
                    DebugLog.log(int0 + " files to go");
                }

                if (CoopSlave.instance != null && int0 % 10 == 0) {
                    CoopSlave.instance.sendMessage("softreset-remaining", null, Integer.toString(int0));
                }
            }
        }

        GameServer.ResetID = Rand.Next(10000000);
        ServerOptions.instance.putSaveOption("ResetID", String.valueOf(GameServer.ResetID));
        IsoWorld.instance.CurrentCell = null;
        DebugLog.log("soft-reset complete, server terminated");
        if (CoopSlave.instance != null) {
            CoopSlave.instance.sendMessage("softreset-finished", null, "");
        }

        SteamUtils.shutdown();
        System.exit(0);
    }

    private static void deleteFile(String string) {
        File file = new File(zombie.ZomboidFileSystem.instance.getGameModeCacheDir() + File.separator + GameServer.ServerName + File.separator + string);
        file.delete();
    }
}
